package com.minimalist.lindi.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.lang.Assert;
import cn.hutool.http.HttpStatus;
import com.minimalist.common.config.exception.BusinessException;
import com.minimalist.common.config.mybatis.bo.PageResp;
import com.minimalist.common.entity.basic.vo.file.FileVO;
import com.minimalist.common.entity.lindi.po.LindiTradeApplicationCredit;
import com.minimalist.common.entity.lindi.vo.tradeapplicationcredit.LindiTradeApplicationCreditQueryVO;
import com.minimalist.common.entity.lindi.vo.tradeapplicationcredit.LindiTradeApplicationCreditVO;
import com.minimalist.common.feign.client.basic.FileFeignClient;
import com.minimalist.common.response.R;
import com.minimalist.common.utils.UnqIdUtil;
import com.minimalist.lindi.mapper.LindiTradeApplicationCreditMapper;
import com.minimalist.lindi.service.LindiTradeApplicationCreditService;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 林地指标交易平台_交易申请付款凭证 服务层实现。
 *
 * @author 11987
 * @since 2025-06-04
 */
@Service
public class LindiTradeApplicationCreditServiceImpl extends ServiceImpl<LindiTradeApplicationCreditMapper, LindiTradeApplicationCredit> implements LindiTradeApplicationCreditService{
    private static final Logger logger = LoggerFactory.getLogger(LindiTradeApplicationCreditServiceImpl.class);


    @Autowired
    private LindiTradeApplicationCreditMapper mapper;

    @Autowired
    private FileFeignClient fileFeignClient;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addTradeApplicationCredit(
            LindiTradeApplicationCreditVO tradeApplicationCreditVO){
        LindiTradeApplicationCredit record = BeanUtil.copyProperties(
                tradeApplicationCreditVO,
                LindiTradeApplicationCredit.class);
        record.setCreditId(UnqIdUtil.uniqueId());
        int insert = mapper.insert(record, true);
        Assert.isTrue(insert == 1, () -> new BusinessException("添加交易申请付款凭证失败"));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteTradeApplicationCreditByTradeApplicationCreditId(
            Long tradeApplicationCreditId){
        LindiTradeApplicationCredit record = mapper
                .selectTradeApplicationCreditByTradeApplicationCreditId(
                        tradeApplicationCreditId);
        Assert.notNull(record, () -> new BusinessException("交易申请付款凭证不存在"));
        if (record.getCreditFileId() != null){
            try{
                R<Void> result = fileFeignClient.deleteFile(record.getCreditFileId());
                if (result.getCode() != HttpStatus.HTTP_OK){
                    logger.warn("删除付款凭证文件失败，文件ID: {}, 错误信息: {}", record.getCreditFileId(), result.getMessage());
                }
            } catch (Exception e){
                logger.warn("删除付款凭证文件异常，文件ID: {}, 异常信息: {}", record.getCreditFileId(), e.getMessage());
            }
        }
        int delete = mapper.delete(record);
        Assert.isTrue(delete == 1, () -> new BusinessException("删除交易申请付款凭证失败"));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateTradeApplicationCreditByTradeApplicationCreditId(
            LindiTradeApplicationCreditVO tradeApplicationCreditVO){
        LindiTradeApplicationCredit record = mapper
                .selectTradeApplicationCreditByTradeApplicationCreditId(
                        tradeApplicationCreditVO
                                .getCreditId());
        Assert.notNull(record, () -> new BusinessException("交易申请付款凭证不存在"));
        BeanUtil.copyProperties(tradeApplicationCreditVO, record,
                CopyOptions.create().ignoreNullValue());
        int update = mapper.update(record);
        Assert.isTrue(update == 1, () -> new BusinessException("更新交易申请付款凭证失败"));
    }

    @Override
    public PageResp<LindiTradeApplicationCreditVO> getPageTradeApplicationCreditList(
            LindiTradeApplicationCreditQueryVO queryVO){
        Page<LindiTradeApplicationCredit> page = mapper
                .selectPageTradeApplicationCreditList(queryVO);
        List<LindiTradeApplicationCreditVO> voList = BeanUtil.copyToList(
                page.getRecords(),
                LindiTradeApplicationCreditVO.class);
        return new PageResp<>(voList, voList.size());
    }

    @Override
    public LindiTradeApplicationCreditVO
    getTradeApplicationCreditByTradeApplicationCreditId(
            Long tradeApplicationCreditId){
        LindiTradeApplicationCredit record = mapper
                .selectTradeApplicationCreditByTradeApplicationCreditId(
                        tradeApplicationCreditId);
        Assert.notNull(record, () -> new BusinessException("交易申请付款凭证不存在"));
        LindiTradeApplicationCreditVO lindiTradeApplicationCreditVO = BeanUtil
                .copyProperties(record, LindiTradeApplicationCreditVO.class);
        R<FileVO> result = fileFeignClient.getFileByFileId(record.getCreditFileId());
        Assert.isTrue(result.getCode() == HttpStatus.HTTP_OK
                        && result.getData() != null
                , () -> new BusinessException("获取付款凭证文件失败"));
        lindiTradeApplicationCreditVO.setCreditFile(result.getData());
        return lindiTradeApplicationCreditVO;
    }

    @Override
    public List<LindiTradeApplicationCreditVO> getTradeApplicationCreditListByTradeApplicationId(
            Long tradeApplicationId){
        List<LindiTradeApplicationCredit> records = mapper
                .selectTradeApplicationCreditListByTradeApplicationId(tradeApplicationId);
        List<LindiTradeApplicationCreditVO> voList = BeanUtil.copyToList(
                records, LindiTradeApplicationCreditVO.class);

        // 批量获取文件信息
        List<Long> fileIds = voList.stream()
                .map(LindiTradeApplicationCreditVO::getCreditFileId)
                .filter(fileId -> fileId != null)
                .collect(Collectors.toList());

        if (!fileIds.isEmpty()){
            try{
                R<List<FileVO>> fileResult = fileFeignClient.getFileListByFileIds(fileIds);
                if (fileResult.getCode() == HttpStatus.HTTP_OK && fileResult.getData() != null){
                    List<FileVO> fileList = fileResult.getData();
                    // 将文件信息设置到对应的VO中
                    voList.forEach(vo -> {
                        if (vo.getCreditFileId() != null){
                            fileList.stream()
                                    .filter(file -> vo.getCreditFileId().equals(file.getFileId()))
                                    .findFirst()
                                    .ifPresent(vo::setCreditFile);
                        }
                    });
                }
            } catch (Exception e){
                // 批量获取文件失败时记录日志，但不影响整体查询
                logger.warn("批量获取付款凭证文件失败，文件ID列表: {}", fileIds, e);
            }
        }

        return voList;
    }
}

